home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
c
/
vbccwossrc.lha
/
vbcc
/
pasm
/
instructions.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-07
|
44KB
|
1,298 lines
/* $VER: pasm instructions.c V1.2b (01.02.99)
*
* This file is part of pasm, a portable PowerPC assembler.
* Copyright (c) 1997-98 Frank Wille
*
* pasm is freeware and part of the portable and retargetable ANSI C
* compiler vbcc, copyright (c) 1995-98 by Volker Barthelmann.
* pasm may be freely redistributed as long as no modifications are
* made and nothing is charged for it. Non-commercial usage is allowed
* without any restrictions.
* EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
* SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
*
*
* v1.2b (01.02.99) phx
* Fixed move_symbols() for move-deltas > alignment (e.g. .align 2)
* v1.2 (21.10.98) phx
* @sdarx support for T_DD- and T_DS-type instructions.
* Replaced obsolete R_PPC_TOC16 by real R_PPC_SDAREL16.
* Fixed mfdcr and mtdcr.
* v1.1d (27.09.98) phx
* Optional PPC4xx instructions mfdcr and mtdcr.
* v1.1a (20.06.98) phx
* F_UPDATE. Check rA = rD for update instructions.
* v1.1 (19.06.98) phx
* Multiple small data sections are supported. The new directive
* .sdreg should be used to set the base register.
* Fixed "Extra characters on line" error for "la rN,<symbol>".
* Wrong error message (46) for "la rN,<absSymbol>". Changed to
* error 32: reloc symbol required.
* v1.0 (21.05.98) phx
* tlsync should have been tlbsync.
* mtsrin is a supervisor instruction.
* ME was not checked for rlwxxx.
* mb/me in rldicxx is 6 bit, not 5.
* v0.9 (07.03.98) phx
* Base relative access on external symbol generated wrong
* relocation type.
* R_ADDR16 relocations in code section had wrong offset.
* R_REL14 branches will only get a 2-byte offset, if the output
* format is EHF/ADOS and a relocation- or xref-entry is required.
* v0.8 (14.02.98) phx
* Alignment list for each section. This fixes the problems
* with optimizations.
* v0.7 (02.01.98) phx
* Implemented optimization OPT_FAR_BRANCH.
* v0.6 (30.10.97) phx
* No more warnings for val@l(rA), where val is > 0x7fff.
* Warnings for optional, 64-bit and supervisor instructions
* can be suppressed.
* v0.5 (03.10.97) phx
* Auto-converting (rA) into 0(rA) had lead to conflicts with terms.
* For example: (x+y)(rA)
* v0.4 (05.07.97) phx
* AA bit in BC instructions is set to allow correct EHF reloction
* (by using AmigaDOS HUNK_RELRELOC16. This should be no problem,
* because absolute branches are not supported by EHF anyway.
* Branch prediction with BCA didn't work correctly.
* Relative branches into other sections are allowed, but the
* user will be warned, because not all object formats / linkers
* support it.
* Omitting zero in load/store instructions is allowed, e.g.
* "rD,(rA)" will be converted into "rD,0(rA)".
* R_PPC_TOC16 support for T_DD- and T_DS-type instructions.
* v0.3 (05.04.97) phx
* An external symbol@l/h/ha, used in d(Rn) addressing mode, got
* R_PPC_ADDR16 relocation instead R_PPC_ADDR16_LO/HI/HA.
* Little-endian support.
* v0.2 (25.03.97) phx
* Writes ELF object for 32-bit PowerPC big-endian. Either absolute
* or ELF output format may be selected. ELF is default for all
* currently supported platforms. PPCasm supports nine different
* relocation types (there are much more...).
* Compiles and works also under NetBSD/amiga (68k).
* Changed function declaration to 'new style' in all sources
* (to avoid problems with '...' for example).
* @l/h/ha is allowed for all displacements.
* v0.1 (11.03.97) phx
* First test version with all PowerPC instructions and most
* important directives. Only raw, absolute output.
* Although all 32- and 64-bit PowerPC instructions are imple-
* mented, too few are really tested till now. I'm expecting many
* bugs in this long list.
* 'la' is the only extended mnemonic, which was implemented as a
* real instruction and not by a macro. It is possible to imple-
* ment all extended mnemonics here, but it would be much work.
* Maybe later, to improve speed. ;)
* v0.0 (21.02.97) phx
* File created.
*/
#define INSTRUCTIONS_C
#include "ppcasm.h"
void instr(struct GlobalVars *,struct ParsedLine *);
char *check_comma(char *);
void pcadd(struct GlobalVars *,unsigned long);
void store_byte(struct GlobalVars *,uint8);
void store_half(struct GlobalVars *,uint16);
void store_word(struct GlobalVars *,uint32);
void store_float(struct GlobalVars *,double);
void store_double(struct GlobalVars *,double);
void store_space(struct GlobalVars *,unsigned long);
static void opt_far_branch(struct GlobalVars *,struct ParsedLine *,
uint32 *,uint32 *,int32 *,char *);
static void swapops(uint32 *,uint32 *);
static int count_operands(struct GlobalVars *,char *);
static bool chk_regindir(char *);
static void move_symbols(struct GlobalVars *,uint32,int32);
static void move_aligned_symbols_offset(struct GlobalVars *,
struct AlignPoint *,uint32,int32);
static void move_aligned_symbols_all(struct GlobalVars *gv,
struct AlignPoint *ap,int32);
struct CPUInstr instructions[] = {
/* standard PowerPC instruction set */
{ 0,"add",0,T_X,31,0,0,(0<<10)+(266<<1)+0 },
{ 0,"add.",0,T_X,31,0,0,(0<<10)+(266<<1)+1 },
{ 0,"addo",0,T_X,31,0,0,(1<<10)+(266<<1)+0 },
{ 0,"addo.",0,T_X,31,0,0,(1<<10)+(266<<1)+1 },
{ 0,"addc",0,T_X,31,0,0,(0<<10)+(10<<1)+0 },
{ 0,"addc.",0,T_X,31,0,0,(0<<10)+(10<<1)+1 },
{ 0,"addco",0,T_X,31,0,0,(1<<10)+(10<<1)+0 },
{ 0,"addco.",0,T_X,31,0,0,(1<<10)+(10<<1)+1 },
{ 0,"adde",0,T_X,31,0,0,(0<<10)+(138<<1)+0 },
{ 0,"adde.",0,T_X,31,0,0,(0<<10)+(138<<1)+1 },
{ 0,"addeo",0,T_X,31,0,0,(1<<10)+(138<<1)+0 },
{ 0,"addeo.",0,T_X,31,0,0,(1<<10)+(138<<1)+1 },
{ 0,"addi",F_SIGNED,T_DI,14,0,0,0 },
{ 0,"addic",F_SIGNED,T_DI,12,0,0,0 },
{ 0,"addic.",F_SIGNED,T_DI,13,0,0,0 },
{ 0,"addis",F_SIGNED,T_DI,15,0,0,0 },
{ 0,"addme",F_SUPP_B,T_X,31,0,0,(0<<10)+(234<<1)+0 },
{ 0,"addme.",F_SUPP_B,T_X,31,0,0,(0<<10)+(234<<1)+1 },
{ 0,"addmeo",F_SUPP_B,T_X,31,0,0,(1<<10)+(234<<1)+0 },
{ 0,"addmeo.",F_SUPP_B,T_X,31,0,0,(1<<10)+(234<<1)+1 },
{ 0,"addze",F_SUPP_B,T_X,31,0,0,(0<<10)+(202<<1)+0 },
{ 0,"addze.",F_SUPP_B,T_X,31,0,0,(0<<10)+(202<<1)+1 },
{ 0,"addzeo",F_SUPP_B,T_X,31,0,0,(1<<10)+(202<<1)+0 },
{ 0,"addzeo.",F_SUPP_B,T_X,31,0,0,(1<<10)+(202<<1)+1 },
{ 0,"and",F_SWAP,T_X,31,0,0,(28<<1)+0 },
{ 0,"and.",F_SWAP,T_X,31,0,0,(28<<1)+1 },
{ 0,"andc",F_SWAP,T_X,31,0,0,(60<<1)+0 },
{ 0,"andc.",F_SWAP,T_X,31,0,0,(60<<1)+1 },
{ 0,"andi.",F_SWAP,T_DI,28,0,0,0 },
{ 0,"andis.",F_SWAP,T_DI,29,0,0,0 },
{ 0,"b",F_SIGNED,T_I,18,0,0,0 },
{ 0,"bl",F_SIGNED,T_I,18,0,0,1 },
{ 0,"ba",0,T_I,18,0,0,2 },
{ 0,"bla",0,T_I,18,0,0,3 },
{ 0,"bc",F_SIGNED,T_B,16,0,0,0 },
{ 0,"bcl",F_SIGNED,T_B,16,0,0,1 },
{ 0,"bca",0,T_B,16,0,0,2 },
{ 0,"bcla",0,T_B,16,0,0,3 },
{ 0,"bcctr",0,T_XLB,19,0,0,(528<<1)+0 },
{ 0,"bcctrl",0,T_XLB,19,0,0,(528<<1)+1 },
{ 0,"bclr",0,T_XLB,19,0,0,(16<<1)+0 },
{ 0,"bclrl",0,T_XLB,19,0,0,(16<<1)+1 },
{ 0,"cmp",0,T_CMP,31,0,0,(0<<1) },
{ 0,"cmpl",0,T_CMP,31,0,0,(32<<1) },
{ 0,"cmpi",F_SIGNED|F_SUPP_B,T_CMP,11,0,0,0 },
{ 0,"cmpli",F_SUPP_B,T_CMP,10,0,0,0 },
{ 0,"cntlzd",F_SWAP|F_SUPP_B|F_64BIT,T_X,31,0,0,(58<<1)+0 },
{ 0,"cntlzd.",F_SWAP|F_SUPP_B|F_64BIT,T_X,31,0,0,(58<<1)+1 },
{ 0,"cntlzw",F_SWAP|F_SUPP_B,T_X,31,0,0,(26<<1)+0 },
{ 0,"cntlzw.",F_SWAP|F_SUPP_B,T_X,31,0,0,(26<<1)+1 },
{ 0,"crand",0,T_X,19,0,0,(257<<1) },
{ 0,"crandc",0,T_X,19,0,0,(129<<1) },
{ 0,"creqv",0,T_X,19,0,0,(289<<1) },
{ 0,"crnand",0,T_X,19,0,0,(225<<1) },
{ 0,"crnor",0,T_X,19,0,0,(33<<1) },
{ 0,"cror",0,T_X,19,0,0,(449<<1) },
{ 0,"crorc",0,T_X,19,0,0,(417<<1) },
{ 0,"crxor",0,T_X,19,0,0,(193<<1) },
{ 0,"dcbf",F_SUPP_D,T_X,31,0,0,